package thread;

import java.util.Random;
import java.util.concurrent.*;

public class ForkJoinPoolTest {
    public static void main(String[] args){
//        testForkJoinPool();
        sum();
    }

    public static void testForkJoinPool(){
        ForkJoinPool pool = new ForkJoinPool();
        pool.submit(new PrintTask(0,300));
        try {
            pool.awaitTermination(2,TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        pool.shutdown();
    }

    public static void sum(){
        int n =100;
        int[] arr = new int[n];
        Random random = new Random();
        int total = 0;
        for (int i = 0,len = arr.length; i < len; i++) {
            int tmp = random.nextInt(20);
            arr[i] = tmp;
            total+=tmp;
        }
        System.out.println("total:"+total);
        ForkJoinPool pool = new ForkJoinPool();
        Future<Integer> future = pool.submit(new CalTask(arr,0,arr.length));
        try {
            System.out.println("future get:"+future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        pool.shutdown();
    }
}

class PrintTask extends RecursiveAction{
    private static final int THRESHOLD = 50;
    private int start;
    private int end;
    public PrintTask(int start,int end){
        this.start = start;
        this.end = end;
    }

    @Override
    protected void compute() {
        if (end -start <THRESHOLD){
            for (int i = start; i < end; i++) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"的i值:"+i);
            }
        }else {
            int middle = (start+end)/2;
            PrintTask left = new PrintTask(start,middle);
            PrintTask right = new PrintTask(middle,end);
            left.fork();
            right.fork();
        }
    }

}
class CalTask extends RecursiveTask<Integer>{
    //每个“小任务”最多只累加20个数
    private static final int THRESHOLD = 20;
    private int arr[];
    private int start;
    private int end;

    //累加从start到end的数组元素
    public CalTask(int[] arr,int start,int end){
        this.arr = arr;
        this.start =start;
        this.end = end;
    }
    @Override
    protected Integer compute() {
        int sum = 0;
        //当end与start之间的差小于THRESHOLD时，开始进行实际累加
        if (end-start<THRESHOLD){
            for (int i = start; i < end; i++) {
                sum +=arr[i];
            }
            return sum;
        }else {
            //当end与start之间的差大于THRESHOLD时，将大任务分解成两个“小任务”
            int middle = (start+end)/2;
            CalTask left = new CalTask(arr,start,middle);
            CalTask right = new CalTask(arr,middle,end);
            //执行两个“小任务”
            left.fork();
            right.fork();
            //把两个“小任务”累加的结果合并起来
            return left.join()+right.join();
        }
    }
}
